package com.faithbj.service.statistics;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.faithbj.common.model.CheckTotal;
import com.faithbj.common.model.Region;
import com.faithbj.common.model.User;
import com.faithbj.common.model.compare.CompareRecord;
import com.faithbj.common.utils.DateUtils;
import com.faithbj.constant.Constant;
import com.faithbj.model.conditions.InWorkTimeOverStatResult;
import com.faithbj.model.conditions.OutWorkTimeOverStatResult;
import com.faithbj.model.conditions.StreetOutTimeOverData;
import com.faithbj.model.conditions.StreetWorkloadStatData;
import com.faithbj.model.conditions.WorkloadStatResult;
import com.faithbj.process.State;
import com.faithbj.process.stats.JbpmStatsService;
import com.faithbj.service.CheckTotalService;
import com.faithbj.service.CompareRecordService;
import com.faithbj.support.fp.Tuple3;

@Service
public class WorkStatService {
	
	@Resource
	private CheckTotalService checkTotalService;
	@Resource
	private CompareRecordService compareRecordService;
	@Resource 
	private JbpmStatsService jbpmStatService;
	
	public List<WorkloadStatResult> getWorkloadData(Date from, Date to, User user, List<Region> countryRegion) {
		Map uploadCondtion = new HashMap();
		uploadCondtion.put("acceptStartTime", from);
		uploadCondtion.put("acceptEndTime", to);
		List<CheckTotal> checkTotalList = checkTotalService.queryCheckTotalListByCondition(uploadCondtion);
		
		Map sendCondition = new HashMap();
		sendCondition.put("startCreateTime", from);
		sendCondition.put("endCreateTime", to);
		List<CompareRecord> sendRecord = compareRecordService.queryCompareRecordListByCondition(sendCondition);
		
		Map recvConditionMap = new HashMap();
		recvConditionMap.put("startUpdateTime", from);
		recvConditionMap.put("endUpdateTime", to);
		List<CompareRecord> recvRecord = compareRecordService.queryCompareRecordListByCondition(recvConditionMap);
		
		Map<String, Long> uploadMap = new HashMap<String, Long>();
		for(CheckTotal checkTotal : checkTotalList) {
			String regionId = checkTotal.getRegionId();
			if(uploadMap.get(regionId) != null) {
				uploadMap.put(regionId, uploadMap.get(regionId) + 1);
			} else {
				uploadMap.put(regionId, new Long("1"));
			}
		}
		
		Map<String, Long> sendRecordMap = new HashMap<String, Long>();
		Map<String, Integer> checkTotalMap = new HashMap<String, Integer>();
		for(CompareRecord record : sendRecord) {
			if(record.getMemberNum().equals(record.getSendNum())) {
				if(checkTotalMap.get(record.getApplyNum()) == null){
					checkTotalMap.put(record.getApplyNum(), 1);
				} else {
					checkTotalMap.put(record.getApplyNum(), checkTotalMap.get(record.getApplyNum())+1);
				}
				if(checkTotalMap.get(record.getApplyNum()).intValue() == 7) {
					String regionId = record.getRegionId();
					if(sendRecordMap.get(regionId) != null) {
						sendRecordMap.put(regionId, sendRecordMap.get(regionId) + 1);
					} else {
						sendRecordMap.put(regionId, new Long("1"));
					}
				}				
			}			
		}
		
		Map<String, Long> recvRecordMap = new HashMap<String, Long>();
		checkTotalMap = new HashMap<String, Integer>();
		for(CompareRecord record : recvRecord) {
			if(record.getMemberNum().equals(record.getRecvNum())) {
				if(checkTotalMap.get(record.getApplyNum()) == null){
					checkTotalMap.put(record.getApplyNum(), 1);
				} else {
					checkTotalMap.put(record.getApplyNum(), checkTotalMap.get(record.getApplyNum())+1);
				}
				if(checkTotalMap.get(record.getApplyNum()).intValue() == 7) {
					String regionId = record.getRegionId();
					if(recvRecordMap.get(regionId) != null) {
						recvRecordMap.put(regionId, recvRecordMap.get(regionId) + 1);
					} else {
						recvRecordMap.put(regionId, new Long("1"));
					}
				}			
			}
		}	
		String regionId = "";
		if(user != null && user.getRegion() != null) {
			regionId = user.getRegion().getId();
		} 
		
		Map<String, Map<State, Long>> resultMap = new HashMap<String, Map<State, Long>>();
		resultMap = jbpmStatService.countGroupByApplyStateInRegion(regionId, from, to);			
		
		List<WorkloadStatResult> result = new ArrayList<WorkloadStatResult>();
		if(countryRegion == null){
			countryRegion = new ArrayList<Region>();
		}
		for(Region region : countryRegion) {
			if(region.getChildren() == null || region.getChildren().size() == 0){
				continue;
			}
			WorkloadStatResult workloadStatResult = new WorkloadStatResult();
			workloadStatResult.setCountryRegionName(region.getName());
			List<StreetWorkloadStatData> streetDataList = new ArrayList<StreetWorkloadStatData>();
			for(Region streetRegion : region.getChildren()) {
				StreetWorkloadStatData data = new StreetWorkloadStatData();
				data.setStreetRegionName(streetRegion.getName());
				data.setSendNum(sendRecordMap.get(streetRegion.getId())==null?0:sendRecordMap.get(streetRegion.getId()));
				data.setRecvNum(recvRecordMap.get(streetRegion.getId())==null?0:recvRecordMap.get(streetRegion.getId()));
				data.setUploadNum(uploadMap.get(streetRegion.getId())==null?0:uploadMap.get(streetRegion.getId()));
				
				Map<State, Long> stateMap = resultMap.get(streetRegion.getId());
				if(stateMap != null){
					Iterator it = stateMap.keySet().iterator();
					while(it.hasNext()) {
						State key = (State)it.next();
						Long value = stateMap.get(key);
						if(key.getId().equals(Constant.PAUSE_CHECK_STATE)) {
							data.setPauseNum(value);
						} else if(key.getId().equals(Constant.CHECK_REPORT_STATE)) {
							data.setReportNum(value);
						} else if(key.getId().equals(Constant.TERMINAL_CHECK_STATE)) {
							data.setTerminalNum(value);
						}
					}
				}				
				streetDataList.add(data);
			}
			workloadStatResult.setStreetStatDataList(streetDataList);
			result.add(workloadStatResult);
		}
		
		return result;
	}
	
	public List<OutWorkTimeOverStatResult> getOutWorkTimeOverData(Date from ,Date to, User user, List<Region> countryRegion) {
		//Map(区域ID, Map(状态, List<元组>)). 状态为信息录入、信息核实两个状态. 元组定义: (开始时间, 截止时间, 操作时间)
		String regionId = "";
		if(user != null && user.getRegion() != null) {
			regionId = user.getRegion().getId();
		} 
		Map<String, Map<State, List<Tuple3<Date, Date, Date>>>> resultMap = new HashMap<String, Map<State, List<Tuple3<Date, Date, Date>>>>();
		resultMap = jbpmStatService.getTimingDetailsInInputPhaseDeadlineDuring(regionId, from, to);
		
		List<OutWorkTimeOverStatResult> result = new ArrayList<OutWorkTimeOverStatResult>();
		
		if(countryRegion == null){
			countryRegion = new ArrayList<Region>();
		}
		for(Region region : countryRegion) {
			if(region.getChildren() == null || region.getChildren().size() == 0){
				continue;
			}
			OutWorkTimeOverStatResult outWorkResult = new OutWorkTimeOverStatResult();
			outWorkResult.setCountryRegionName(region.getName());
			List<StreetOutTimeOverData> dataList = new ArrayList<StreetOutTimeOverData>();
			for(Region streetRegion : region.getChildren()) {
				StreetOutTimeOverData data = new StreetOutTimeOverData();
				data.setStreetRegionName(streetRegion.getName());
				Integer timeOverSumOfPerson = 0;
				Map<State, List<Tuple3<Date, Date, Date>>> stateMap = resultMap.get(streetRegion.getId());
				if(stateMap != null){
					Iterator it = stateMap.keySet().iterator();
					while(it.hasNext()) {
						State state = (State)it.next();
						List<Tuple3<Date, Date, Date>> valueList = stateMap.get(state);
						int maxTimeOutDates = getMaxTimeOutDates(valueList);
						if(state.getId().equals(Constant.INPUT_STATE)) {
							data.setTimeOverNumOfInput(valueList.size());
							data.setTimeOverMaxDaysOfInput(maxTimeOutDates);						
						} else if(state.getId().equals(Constant.STREET_CHECK_STATE)) {
							data.setTimeOverNumOfCheck(valueList.size());
							data.setTimeOverMaxDaysOfCheck(maxTimeOutDates);
						}
						timeOverSumOfPerson = timeOverSumOfPerson + valueList.size();
					}	
				}				
				data.setTimeOverSum(timeOverSumOfPerson);
				dataList.add(data);
			}
			outWorkResult.setStreetTimeoverDataList(dataList);
			result.add(outWorkResult);
		}
	
		return result;
	}

	public List<InWorkTimeOverStatResult> getInWorkTimeOverData(Date from, Date to) {
		//Map(操作人名字, Map(状态, List<元组>)). 状态为标准审核、比对审核、抽查三个状态. 元组定义: (开始时间, 截止时间, 操作时间)
		Map<String, Map<State, List<Tuple3<Date, Date, Date>>>> resultMap = new HashMap<String, Map<State, List<Tuple3<Date, Date, Date>>>>();
		resultMap = jbpmStatService.getTimingDetailsInVerifyPhaseDeadlineDuring(from, to);
		
		List<InWorkTimeOverStatResult> result = new ArrayList<InWorkTimeOverStatResult>();
		
		Iterator it = resultMap.keySet().iterator();
		while(it.hasNext()) {
			String name = (String)it.next();			
			InWorkTimeOverStatResult inResult = new InWorkTimeOverStatResult();
			inResult.setPersonName(name);			
			Map<State, List<Tuple3<Date, Date, Date>>> stateMap = resultMap.get(name);
			Iterator itInner = stateMap.keySet().iterator();
			Integer sumTimeOutNumOfPerson = 0;
			while(itInner.hasNext()) {
				State keyInner = (State)itInner.next();
				List<Tuple3<Date, Date, Date>> valueInner = stateMap.get(keyInner);
				int maxTimeOutDates = getMaxTimeOutDates(valueInner);
				if(keyInner.getId().equals(Constant.ACCESS_CHECK_STATE)) {
					inResult.setTimeoverNumOfEntry(valueInner.size());
					inResult.setTimeoverMaxDaysOfEntry(maxTimeOutDates);
				} else if(keyInner.getId().equals(Constant.FIRST_CHECK_STATE)) {
					inResult.setTimeoverNumOfFirstCheck(valueInner.size());
					inResult.setTimeoverMaxDaysOfFirstCheck(maxTimeOutDates);
				} else if(keyInner.getId().equals(Constant.SECOND_CHECK_STATE)) {
					inResult.setTimeoverNumOfSecondCheck(valueInner.size());
					inResult.setTimeoverMaxDaysOfSecondCheck(maxTimeOutDates);
				}	
				sumTimeOutNumOfPerson = sumTimeOutNumOfPerson + valueInner.size();
			}
			inResult.setTimeoverSum(sumTimeOutNumOfPerson);
			result.add(inResult);
		}
	
		return result;
	}

	private int getMaxTimeOutDates(List<Tuple3<Date, Date, Date>> valueInner) {
		int maxTimeOutDates = 0;
		for(Tuple3 time : valueInner) {
			Date startDate = (Date)time._1();
			Date endDate = (Date)time._2();
			Date operateDate = (Date)time._3();
			if(operateDate == null) {
				operateDate = new Date();//如果操作时间为空，说明当前时间还没有操作
			}
			if(endDate.after(operateDate)) {
				continue;
			}
			Long diffDates = this.getDiffDays(operateDate, endDate);
			int diff = diffDates.intValue();
			if(diff > maxTimeOutDates) {
				maxTimeOutDates = diff;
			}
		}
		return maxTimeOutDates;
	}
	
	/**
	 * 计算date1比date2晚多少天
	 * @param date1 实际操作时间	
	 * @param date2 应截止时间
	 * @return
	 */
	private static Long getDiffDays(Date date1, Date date2) {
		date1 = new Date(date1.getYear(), date1.getMonth(), date1.getDate());
		date2 = new Date(date2.getYear(), date2.getMonth(), date2.getDate());
		Long quot = new Long("0");
		quot = date1.getTime() - date2.getTime();
		quot = quot / 1000 / 60 / 60 / 24;
		return quot;
	}
	
	public static void main(String args[]) {
		String date = "2012-06-22 12:00:00";
		Date date1 = DateUtils.getStringToDate(date, "yyyy-MM-dd HH:mm:ss");
		Date date2 = new Date();
		Long day = getDiffDays(date1,date2);
		System.out.println( "距离 "+date1+" 还有 "+day+" 天" );
	}
}
